package com.seng.resourcetycoon.manager;

import com.seng.resourcetycoon.services.LoadBearerService;
import com.seng.resourcetycoon.services.GamePlayService;
import com.seng.resourcetycoon.services.GameStateHandler;
import com.seng.resourcetycoon.services.TowerManagementService;

import java.util.ArrayList;
import java.util.List;

/**
 * GameStateHandlerManager acts as a centralized manager for various game states,
 * ensuring that each state is initialized, begun, suspended, resumed, and cleaned up
 * in a controlled and consistent manner. It coordinates with different services
 * related to cart management, tower management, and event handling, encapsulating
 * the complexity of managing multiple game states.
 */
public class GameStateHandlerManager implements GameStateHandler {

    /** A list containing all registered GameStateHandlers to be managed. */
    private final List<GameStateHandler> gameStateHandlers;

    /**
     * Constructs a GameStateHandlerManager with the necessary service dependencies.
     * Upon initialization, it registers itself as a handler for the provided services.
     *
     * @param cartManagerService   Service responsible for managing in-game purchases.
     * @param towerManagementService Manages tower-related gameplay aspects.
     * @param eventManager         Coordinates events within the game.
     */
    public GameStateHandlerManager(LoadBearerService cartManagerService,
                                   TowerManagementService towerManagementService,
                                   EventManager eventManager) {

        this.gameStateHandlers = new ArrayList<>();

        // Registers the services as GameStateHandlers.
        registerGameState(cartManagerService);
        registerGameState(towerManagementService);
        registerGameState(eventManager);
    }

    /**
     * Registers a GameStateHandler with the manager, allowing it to participate in
     * the lifecycle management of the game states.
     *
     * @param gameStateHandler The GameStateHandler instance to be registered.
     */
    public void registerGameState(GameStateHandler gameStateHandler) {
        gameStateHandlers.add(gameStateHandler);
    }

    /**
     * Initializes all registered GameStateHandlers, preparing them for gameplay.
     * Exceptions during initialization are caught and logged to standard error.
     *
     * @param gamePlayService The service providing context for game initialization.
     */
    @Override
    public void initialize(GamePlayService gamePlayService) {
        gameStateHandlers.forEach(state -> {
            try {
                state.initialize(gamePlayService);
            } catch (Exception e) {
                System.err.println("Error initializing game state: " + e.getMessage());
            }
        });
    }

    /**
     * Instructs all GameStateHandlers to begin their respective processes.
     */
    @Override
    public void begin() {
        gameStateHandlers.forEach(GameStateHandler::begin);
    }

    /**
     * Suspends the operation of all GameStateHandlers.
     */
    @Override
    public void suspend() {
        gameStateHandlers.forEach(GameStateHandler::suspend);
    }

    /**
     * Continues the processing of all suspended GameStateHandlers.
     */
    @Override
    public void continueProcessing() {
        gameStateHandlers.forEach(GameStateHandler::continueProcessing);
    }

    /**
     * Cleans up resources held by all GameStateHandlers when the game ends or transitions.
     * Exceptions during cleanup are caught and logged to standard error.
     *
     * @param gamePlayService The service providing context for resource cleanup.
     */
    @Override
    public void cleanup(GamePlayService gamePlayService) {
        gameStateHandlers.forEach(state -> {
            try {
                state.cleanup(gamePlayService);
            } catch (Exception e) {
                System.err.println("Error disposing game state: " + e.getMessage());
            }
        });
    }
}
